package transport

import (
	"consul_grpc/endpoint"
	grpc_health_v1 "consul_grpc/grpc.health.v1"
	"consul_grpc/pb"
	"context"

	"github.com/go-kit/kit/transport/grpc"
)

//类似Grpc服务的处理路由
type grpcServer struct {
	HealthCheckHandler grpc.Handler
	GreetHandler       grpc.Handler
	DiscoveryHandler   grpc.Handler
}

//三个服务的解码，解码成逻辑层所识别的格式
func DecodeHealthCheckRequest(ctx context.Context, r interface{}) (interface{}, error) {
	return endpoint.HealthRequest{}, nil
}
func DecodeGreetRequest(ctx context.Context, r interface{}) (interface{}, error) {
	req := r.(*pb.GreetRequest)
	return endpoint.GreetRequest{
		Name: req.Name,
	}, nil
}
func DecodeDiscoveryRequest(ctx context.Context, r interface{}) (interface{}, error) {
	req := r.(*pb.DiscoveryRequest)
	return endpoint.DiscoveryRequest{
		ServiceName: req.ServiceName,
	}, nil
}

//三个服务的编码，编码成pb层可处理的格式
func EncodeHealthCheckResponse(_ context.Context, r interface{}) (interface{}, error) {
	resp := r.(endpoint.HealthResponse)
	return &pb.HealthCheckResponse{
		Status: resp.Status,
	}, nil
}
func EncodeGreetCheckResponse(_ context.Context, r interface{}) (interface{}, error) {
	resp := r.(endpoint.GreetResponse)
	return &pb.GreetResponse{
		Reply: resp.Reply,
	}, nil
}
func EncodeDiscoveryCheckResponse(_ context.Context, r interface{}) (interface{}, error) {
	resp := r.(endpoint.DiscoveryResponse)
	return &pb.DiscoveryResponse{
		ResBuf: resp.ResBuf,
		Error:  resp.Error,
	}, nil
}

//初始化一个Grpc服务处理实例
func NewGrpcServer(ctx context.Context, endpoints endpoint.ConsulGrpcEndpoint) pb.ConsulGrpcServerServer {
	return &grpcServer{
		HealthCheckHandler: grpc.NewServer(
			endpoints.HealthEndpoint,  //该服务的相关处理方法
			DecodeHealthCheckRequest,  //解码grpc来的参数成HealthEndpoint支持的参数格式
			EncodeHealthCheckResponse, //编码HealthEndpoint返回的response至grpc
		),
		GreetHandler: grpc.NewServer(
			endpoints.GreetEndpoint,
			DecodeGreetRequest,
			EncodeGreetCheckResponse,
		),
		DiscoveryHandler: grpc.NewServer(
			endpoints.DiscoveryEndpoint,
			DecodeDiscoveryRequest,
			EncodeDiscoveryCheckResponse,
		),
	}
}

//具体grpc方法实现
func (s *grpcServer) HealthCheck(ctx context.Context, r *pb.HealthCheckRequest) (*pb.HealthCheckResponse, error) {
	_, resp, err := s.HealthCheckHandler.ServeGRPC(ctx, r)
	if err != nil {
		return nil, err
	}
	return resp.(*pb.HealthCheckResponse), nil
}
func (s *grpcServer) Greet(ctx context.Context, r *pb.GreetRequest) (*pb.GreetResponse, error) {
	_, resp, err := s.GreetHandler.ServeGRPC(ctx, r)
	if err != nil {
		return nil, err
	}
	return resp.(*pb.GreetResponse), nil
}
func (s *grpcServer) Discovery(ctx context.Context, r *pb.DiscoveryRequest) (*pb.DiscoveryResponse, error) {
	_, resp, err := s.DiscoveryHandler.ServeGRPC(ctx, r)
	if err != nil {
		return nil, err
	}
	return resp.(*pb.DiscoveryResponse), nil
}

//Grpc服务在Consul的健康检测，基于grpc.health.v1
type GrpcHealthV1Impl struct{}

//初始化一个服务健康检测实例
func NewGrpcHealthV1Server() grpc_health_v1.HealthServer {
	return &GrpcHealthV1Impl{}
}

//实现相关方法，用于心跳响应
func (h *GrpcHealthV1Impl) Check(ctx context.Context, req *grpc_health_v1.HealthCheckRequest) (*grpc_health_v1.HealthCheckResponse, error) {
	return &grpc_health_v1.HealthCheckResponse{
		Status: grpc_health_v1.HealthCheckResponse_SERVING,
	}, nil
}

func (h *GrpcHealthV1Impl) Watch(*grpc_health_v1.HealthCheckRequest, grpc_health_v1.Health_WatchServer) error {
	return nil
}
